package com.hockeo.client.ui.panels;

import java.util.HashMap;
import java.util.Map;

import com.extjs.gxt.ui.client.event.ButtonEvent;
import com.extjs.gxt.ui.client.event.SelectionChangedEvent;
import com.extjs.gxt.ui.client.event.SelectionChangedListener;
import com.extjs.gxt.ui.client.event.SelectionListener;
import com.extjs.gxt.ui.client.util.Margins;
import com.extjs.gxt.ui.client.widget.ContentPanel;
import com.extjs.gxt.ui.client.widget.button.Button;
import com.extjs.gxt.ui.client.widget.form.LabelField;
import com.extjs.gxt.ui.client.widget.layout.BorderLayoutData;
import com.extjs.gxt.ui.client.widget.layout.HBoxLayout;
import com.extjs.gxt.ui.client.widget.layout.HBoxLayoutData;
import com.extjs.gxt.ui.client.widget.layout.BoxLayout.BoxLayoutPack;
import com.extjs.gxt.ui.client.widget.layout.HBoxLayout.HBoxLayoutAlign;
import com.google.gwt.user.client.Window;
import com.hockeo.client.VHMain;
import com.hockeo.client.model.JSData;
import com.hockeo.client.model.JSSimpleData;
import com.hockeo.client.res.AppConstants;
import com.hockeo.client.ui.base.VHCenterPanelContent;
import com.hockeo.client.ui.base.VHEditorGrid;
import com.hockeo.client.ui.base.VHPanel;
import com.hockeo.client.ui.base.VHSimpleComboBox;
import com.hockeo.client.ui.widgets.GridDataEditorAssociation;

/**
 * VH admin data editor.
 *
 * @version $Id$
 * @author jjanke
 */
public class DataEditor extends VHPanel implements VHCenterPanelContent
{
  private static DataEditor               d_instance;
  private String                          d_strCurrentDataType;
  private final Map<String, VHEditorGrid> d_mapEditors = new HashMap<String, VHEditorGrid>();
  private Button                          d_btnAdd;
  private Button                          d_btnReset;
  private Button                          d_btnSave;

  private DataEditor()
  {
    final AppConstants consts = VHMain.getAppConstants();
    BorderLayoutData data;

    // Northern panel
    //
    HBoxLayoutData hboxLayoutData = new HBoxLayoutData( new Margins( 0, 4, 0, 0 ) );
    HBoxLayout hboxLayout = new HBoxLayout();
    hboxLayout.setHBoxLayoutAlign( HBoxLayoutAlign.MIDDLE );
    hboxLayout.setPack( BoxLayoutPack.START );

    ContentPanel pnNorth = new ContentPanel( hboxLayout );
    pnNorth.setHeaderVisible( false );

    pnNorth.add( new LabelField( consts.dataEditorLabelEntityTypes() ), new HBoxLayoutData( new Margins( 0, 4, 0, 4 ) ) );

    final VHSimpleComboBox comboEntityTypes = new VHSimpleComboBox();

    comboEntityTypes.setSimpleModels( new JSSimpleData( "Association", consts.dataEditorTypeAssociation() ),
        new JSSimpleData( "Contest", consts.dataEditorTypeContest() ), new JSSimpleData( "ContestRound",
            consts.dataEditorTypeContestRound() ), new JSSimpleData( "Club", consts.dataEditorTypeClub() ) );

    pnNorth.add( comboEntityTypes, hboxLayoutData );

    data = getNorthLayoutData();
    data.setSize( 32f );
    add( pnNorth, data );

    // Southern panel
    //
    hboxLayout = new HBoxLayout();
    hboxLayout.setHBoxLayoutAlign( HBoxLayoutAlign.MIDDLE );
    hboxLayout.setPack( BoxLayoutPack.END );

    ContentPanel pnSouth = new ContentPanel( hboxLayout );
    pnSouth.setHeaderVisible( false );

    EditButtonListener ebl = new EditButtonListener();

    Button btn = new Button( consts.buttonNew() );
    btn.setItemId( "btnNew" );
    btn.addSelectionListener( ebl );
    btn.setWidth( 60 );
    btn.setIcon( VHMain.ICON_ADD );
    btn.setToolTip( consts.buttonNewToolTip() );
    pnSouth.add( btn, hboxLayoutData );
    d_btnAdd = btn;

    btn = new Button( consts.buttonReset() );
    btn.setItemId( "btnReset" );
    btn.addSelectionListener( ebl );
    btn.setWidth( 60 );
    btn.setIcon( VHMain.ICON_CANCEL );
    btn.setToolTip( consts.buttonResetToolTip() );
    pnSouth.add( btn, hboxLayoutData );
    d_btnReset = btn;

    btn = new Button( consts.buttonSave() );
    btn.setItemId( "btnSave" );
    btn.addSelectionListener( ebl );
    btn.setWidth( 60 );
    btn.setIcon( VHMain.ICON_ACCEPT );
    btn.setToolTip( consts.buttonSaveToolTip() );
    pnSouth.add( btn, hboxLayoutData );
    d_btnSave = btn;

    data = getSouthLayoutData();
    data.setSize( 32f );
    add( pnSouth, data );

    // Event handlers
    //
    comboEntityTypes.getCombobox().addSelectionChangedListener( new SelectionChangedListener<JSData>() {
      @Override
      public void selectionChanged( SelectionChangedEvent<JSData> se )
      {
        JSData data = se.getSelectedItem();
        onDataTypeSelected( data.getId() );
      }
    } );

    // Default selections (must be made after all event handlers have been registered)
    //
    comboEntityTypes.selectDefault();
  }

  /**
   * Called when the data type combobox selection changes.
   *
   * @param strSelected the name of the selected data type
   */
  private void onDataTypeSelected( String strSelected )
  {
    // if the selection has not changed, there is nothing to do
    //
    if ( d_strCurrentDataType != null && d_strCurrentDataType.equals( strSelected ) )
      return;

    VHEditorGrid grid = d_mapEditors.get( strSelected );

    if ( grid == null )
    {
      if ( strSelected.equals( "Association" ) )
        grid = new GridDataEditorAssociation();
      else
      {
        Window.alert( "No editor is available for '" + strSelected + "'." );
        return;
      }

      d_mapEditors.put( strSelected, grid );
    }

    grid.loadData();

    setCenterWidget( grid );

    d_strCurrentDataType = strSelected;
  }

  public static DataEditor get()
  {
    if ( d_instance == null )
      d_instance = new DataEditor();

    return d_instance;
  }

  @Override
  public void customiseParent( ContentPanel panelParent )
  {
    panelParent.setHeading( VHMain.getAppConstants().menuDataEditor() );
  }

  /**
   * Common listener for the data editor's control buttons.
   *
   * @version $Id$
   * @author jjanke
   */
  private class EditButtonListener extends SelectionListener<ButtonEvent>
  {
    @Override
    public void componentSelected( ButtonEvent evt )
    {
      final String strItemId = evt.getButton().getItemId();
      final VHEditorGrid grid = (VHEditorGrid) getCenterWidget();

      if ( grid == null )
        return;

      if ( strItemId.equals( "btnNew" ) )
        grid.addLine();
      else if ( strItemId.equals( "btnReset" ) )
        grid.rollbackChanges();
      else if ( strItemId.equals( "btnSave" ) )
        grid.commitChanges();
      else
        Window.alert( "Button '" + evt.getButton().getItemId() + "' pressed." );
    }
  }
}
